{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Valid Number"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Hard"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: isNumber"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #有效数字"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p><strong>有效数字</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>一个 <strong>小数</strong> 或者 <strong>整数</strong></li>\n",
    "\t<li>（可选）一个 <code>'e'</code> 或 <code>'E'</code> ，后面跟着一个 <strong>整数</strong></li>\n",
    "</ol>\n",
    "\n",
    "<p><strong>小数</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>\n",
    "\t<li>下述格式之一：\n",
    "\t<ol>\n",
    "\t\t<li>至少一位数字，后面跟着一个点 <code>'.'</code></li>\n",
    "\t\t<li>至少一位数字，后面跟着一个点 <code>'.'</code> ，后面再跟着至少一位数字</li>\n",
    "\t\t<li>一个点 <code>'.'</code> ，后面跟着至少一位数字</li>\n",
    "\t</ol>\n",
    "\t</li>\n",
    "</ol>\n",
    "\n",
    "<p><strong>整数</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>\n",
    "\t<li>至少一位数字</li>\n",
    "</ol>\n",
    "\n",
    "<p>部分有效数字列举如下：<code>[\"2\", \"0089\", \"-0.1\", \"+3.14\", \"4.\", \"-.9\", \"2e10\", \"-90E3\", \"3e+7\", \"+6e-1\", \"53.5e93\", \"-123.456e789\"]</code></p>\n",
    "\n",
    "<p>部分无效数字列举如下：<code>[\"abc\", \"1a\", \"1e\", \"e3\", \"99e2.5\", \"--6\", \"-+3\", \"95a54e53\"]</code></p>\n",
    "\n",
    "<p>给你一个字符串 <code>s</code> ，如果 <code>s</code> 是一个 <strong>有效数字</strong> ，请返回 <code>true</code> 。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"0\"\n",
    "<strong>输出：</strong>true\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"e\"\n",
    "<strong>输出：</strong>false\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \".\"\n",
    "<strong>输出：</strong>false\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= s.length &lt;= 20</code></li>\n",
    "\t<li><code>s</code> 仅含英文字母（大写和小写），数字（<code>0-9</code>），加号 <code>'+'</code> ，减号 <code>'-'</code> ，或者点 <code>'.'</code> 。</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [valid-number](https://leetcode.cn/problems/valid-number/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [valid-number](https://leetcode.cn/problems/valid-number/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"0\"', '\"e\"', '\".\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        if s == \"E\" or s == \"e\":\n",
    "            return False\n",
    "        sz = len(s)\n",
    "        i = 0\n",
    "        a = \"\"\n",
    "        while i < sz and s[i] not in \"Ee\":\n",
    "            a += s[i]\n",
    "            i += 1\n",
    "        def f1(a):\n",
    "            sz = len(a)\n",
    "            if sz <= 0:\n",
    "                return False\n",
    "            i = 0\n",
    "            if i < sz and a[i] in \"+-\":\n",
    "                i += 1\n",
    "            if i >= sz:\n",
    "                return False\n",
    "            if a[i:] == \".\":\n",
    "                return False\n",
    "            while i < sz and a[i].isnumeric():\n",
    "                i += 1\n",
    "            if i < sz and a[i] != '.':\n",
    "                return False\n",
    "            i += 1\n",
    "            while i < sz and a[i].isnumeric():\n",
    "                i += 1\n",
    "            return i >= sz\n",
    "        if i >= sz:\n",
    "            return f1(a)\n",
    "        if not f1(a):\n",
    "            return False\n",
    "        i += 1\n",
    "        if i < sz and s[i] in \"+-\":\n",
    "            i += 1\n",
    "        if i >= sz:\n",
    "            return False\n",
    "        while i < sz and s[i].isnumeric():\n",
    "            i += 1\n",
    "        return i >= sz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        i, j = 0, len(s) - 1\n",
    "        while i < len(s) and s[i] == ' ':\n",
    "            i += 1\n",
    "        if i == len(s):\n",
    "            return False\n",
    "        while s[j] == ' ':\n",
    "            j -= 1\n",
    "        s = s[i:j + 1]\n",
    "        ePosition = -1\n",
    "        eDigit = False\n",
    "        digit = ['0','1','2','3','4','5','6','7','8','9']\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in digit and s[i] != 'e' and s[i] != '+' and s[i] != '-' and s[i] != '.':\n",
    "                return False\n",
    "            if s[i] == 'e':\n",
    "                if ePosition != -1 or eDigit == False:\n",
    "                    return False\n",
    "                ePosition = i\n",
    "            if s[i] in digit:\n",
    "                eDigit = True\n",
    "        if ePosition != -1:\n",
    "            s1, s2 = s[:ePosition], s[ePosition + 1:]\n",
    "            if len(s2) == 0:\n",
    "                return False\n",
    "            flag = -1\n",
    "            hasDigit = False\n",
    "            for i in range(len(s2)):\n",
    "                if s2[i] == '.':\n",
    "                    return False\n",
    "                if s2[i] == '+' or s2[i] == '-':\n",
    "                    if i > 0:\n",
    "                        return False\n",
    "                if s2[i] in digit:\n",
    "                    hasDigit = True\n",
    "            if hasDigit == False:\n",
    "                return False\n",
    "            dotPosition = -1\n",
    "            hasDigit = False\n",
    "            for i in range(len(s1)):\n",
    "                if s1[i] == '+' or s1[i] == '-':\n",
    "                    if i > 0:\n",
    "                        return False\n",
    "                if s1[i] == '.':\n",
    "                    if dotPosition != -1:\n",
    "                        return False\n",
    "                    dotPosition = i\n",
    "                if s1[i] in digit:\n",
    "                    hasDigit = True\n",
    "            if s1 == \".\":\n",
    "                return False\n",
    "            if hasDigit == False:\n",
    "                return False\n",
    "        else:\n",
    "            dotPosition = -1\n",
    "            hasDigit = False\n",
    "            for i in range(len(s)):\n",
    "                if s[i] == '+' or s[i] == '-':\n",
    "                    if i > 0:\n",
    "                        return False\n",
    "                if s[i] == '.':\n",
    "                    if dotPosition != -1:\n",
    "                        return False\n",
    "                    dotPosition = i\n",
    "                if s[i] in digit:\n",
    "                    hasDigit = True\n",
    "            if hasDigit == False:\n",
    "                return False\n",
    "            if s == \".\":\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        return self.way1(s)\n",
    "    def way1(self,s):#regex\n",
    "        try:\n",
    "            float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def transferState(self, state, c):\n",
    "        signs = ['+', '-']\n",
    "        nums = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\n",
    "        if state == 0:\n",
    "            if c in nums:\n",
    "                return 1\n",
    "            elif c in signs:\n",
    "                return 2\n",
    "            elif c == \".\":\n",
    "                return 3\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 1:\n",
    "            if c in nums:\n",
    "                return 1\n",
    "            elif c == \".\":\n",
    "                return 4\n",
    "            elif c == \"e\":\n",
    "                return 6\n",
    "            elif c == None:\n",
    "                return 10\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 2:\n",
    "            if c in nums:\n",
    "                return 1\n",
    "            elif c == \".\":\n",
    "                return 3\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 3:\n",
    "            if c in nums:\n",
    "                return 7\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 4:\n",
    "            if c in nums:\n",
    "                return 5\n",
    "            elif c == \"e\":\n",
    "                return 6\n",
    "            elif c == None:\n",
    "                return 10\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 5:\n",
    "            if c in nums:\n",
    "                return 5\n",
    "            elif c == \"e\":\n",
    "                return 6\n",
    "            elif c == None:\n",
    "                return 10\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 6:\n",
    "            if c in nums:\n",
    "                return 9\n",
    "            elif c in signs:\n",
    "                return 8\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 7:\n",
    "            if c in nums:\n",
    "                return 7\n",
    "            elif c == \"e\":\n",
    "                return 6\n",
    "            elif c == None:\n",
    "                return 10\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 8:\n",
    "            if c in nums:\n",
    "                return 9\n",
    "            else:\n",
    "                return -1\n",
    "        elif state == 9:\n",
    "            if c in nums:\n",
    "                return 9\n",
    "            elif c == None:\n",
    "                return 10\n",
    "            else:\n",
    "                return -1\n",
    "            \n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        state = 0\n",
    "        s = str.strip(s)\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "        for i in range(len(s)):\n",
    "            state = self.transferState(state, s[i])\n",
    "            if state == -1:\n",
    "                return False\n",
    "        state = self.transferState(state, None)\n",
    "        return state != -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: 'str') -> 'bool':\n",
    "        try:\n",
    "            float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        s = s.strip()\n",
    "        num, exp, operator, dot, length = 0, 0, 0, 0, len(s)\n",
    "        if length == 0:\n",
    "            return False\n",
    "        if length == 1 and not s[0].isnumeric():\n",
    "            return False\n",
    "        if not s[0].isnumeric():\n",
    "            if s[0] == \"-\" or s[0] == \"+\":\n",
    "                operator += 1\n",
    "            elif s[0] == '.':\n",
    "                dot += 1\n",
    "            else:\n",
    "                return False\n",
    "        else:\n",
    "            num += 1\n",
    "        for i in range(1, length):\n",
    "            if not s[i].isnumeric():\n",
    "                if s[i] == 'e':\n",
    "                    exp += 1\n",
    "                    if exp > 1:\n",
    "                        return False\n",
    "                    elif i == length-1:\n",
    "                        return False\n",
    "                    elif not s[i-1].isnumeric() and (s[i-1] != '.' or num == 0):\n",
    "                        return False\n",
    "                elif s[i] == '-' or s[i] == '+':\n",
    "                    operator += 1\n",
    "                    if operator > 1 or s[i-1] != 'e' or i == length-1:\n",
    "                        return False\n",
    "                elif s[i] == '.':\n",
    "                    dot += 1\n",
    "                    if dot > 1 or exp > 0:\n",
    "                        return False\n",
    "                    elif not s[i-1].isnumeric() and (s[i-1] != \"-\" and s[i-1] != \"+\"):\n",
    "                        return False\n",
    "                    elif i == length-1 and not s[i-1].isnumeric():\n",
    "                        return False\n",
    "                else:\n",
    "                    return False\n",
    "            else:\n",
    "                num += 1\n",
    "                operator = 0\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        # 首先去掉字符串首尾的空格字符\n",
    "        s = s.strip()\n",
    "        # num：数字出现的次数，exp：e出现的次数，operator：连续符号出现的次数，dot：点出现的次数，length:s中字符的个数\n",
    "        num, exp, operator, dot, length = 0, 0, 0, 0, len(s)\n",
    "        # 如果没有字符或者只有一个字符且不是数字,返回False\n",
    "        if length == 0 or (length == 1 and not s[0].isnumeric()):\n",
    "            return False\n",
    "        # 如果不止一个字符且首字符不是数字\n",
    "        elif not s[0].isnumeric():\n",
    "            # 如果是\"-\"或者\"+\",operator自增一次\n",
    "            if s[0] == \"-\" or s[0] == \"+\":\n",
    "                operator += 1\n",
    "            # 如果是\".\",dot自增一次\n",
    "            elif s[0] == '.':\n",
    "                dot += 1\n",
    "            # 如果不是数字，且不是\".\",\"-\",\"+\",直接返回Fasle\n",
    "            else:\n",
    "                return False\n",
    "        else:\n",
    "            # 统计数字个数，num自增一次\n",
    "            num += 1\n",
    "        # 从索引为1的位置开始遍历\n",
    "        for i in range(1, length):\n",
    "            # 如果不是数组\n",
    "            if not s[i].isnumeric():\n",
    "                # 如果是字母\"e\"\n",
    "                if s[i] == 'e':\n",
    "                    # exp自增一次\n",
    "                    exp += 1\n",
    "                    # 如果e出现了不止一次，或者e出现在s中最后一个位置，返回False\n",
    "                    if exp > 1 or i == length-1:\n",
    "                        return False\n",
    "                    # 如果e前面不是数字，且前面一个字符不是点号或者前面所有字符中数字一次都没有出现，返回False\n",
    "                    elif not s[i-1].isnumeric() and (s[i-1] != '.' or num == 0):\n",
    "                        return False\n",
    "                elif s[i] == '-' or s[i] == '+':\n",
    "                    operator += 1\n",
    "                    if operator > 1 or s[i-1] != 'e' or i == length-1:\n",
    "                        return False\n",
    "                elif s[i] == '.':\n",
    "                    dot += 1\n",
    "                    if dot > 1 or exp > 0:\n",
    "                        return False\n",
    "                    elif not s[i-1].isnumeric() and (s[i-1] != \"-\" and s[i-1] != \"+\"):\n",
    "                        return False\n",
    "                    elif i == length-1 and not s[i-1].isnumeric():\n",
    "                        return False\n",
    "                else:\n",
    "                    return False\n",
    "            else:\n",
    "                num += 1\n",
    "                operator = 0\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        s = s.lstrip().rstrip()\n",
    "        e, point, num = False, False, False\n",
    "        i, s_len = 0, len(s)\n",
    "        \n",
    "        if s_len > 0 and s[i] in '+-':\n",
    "            i += 1\n",
    "            \n",
    "        while i < s_len:\n",
    "            c = s[i]\n",
    "            if c in '0123456789':\n",
    "                i += 1\n",
    "                num = True\n",
    "                continue\n",
    "            elif c in 'eE':\n",
    "                if not num or e or i == s_len - 1:\n",
    "                    return False\n",
    "                e = True\n",
    "                if s[i+1] in '+-' and i < s_len - 2:\n",
    "                    i += 1   \n",
    "            elif c == '.':\n",
    "                if point or e:\n",
    "                    return False\n",
    "                point = True\n",
    "            else:\n",
    "                return False                \n",
    "\n",
    "            i += 1\n",
    "        return num\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        s = s.strip()\n",
    "        length = len(s)\n",
    "        if length == 0:\n",
    "            return False\n",
    "        try:\n",
    "            num = float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "        def isnoe(s):\n",
    "            if len(s) == 0:\n",
    "                return False\n",
    "            dot = False\n",
    "            for i in range(len(s)):\n",
    "                if (s[i] <'0' or s[i] > '9') and s[i] != '.':\n",
    "                    return False\n",
    "                elif s[i] == '.':\n",
    "                    if len(s) == 1:\n",
    "                        return False\n",
    "                    if dot == False:\n",
    "                        dot = True\n",
    "                    else:\n",
    "                        return False\n",
    "            return True\n",
    "        def isnodot(s):\n",
    "            if len(s) == 0:\n",
    "                return False\n",
    "            for i in range(len(s)):\n",
    "                if (s[i] <'0' or s[i] > '9'):\n",
    "                    return False\n",
    "            return True\n",
    "        if s[0] == '+' or s[0] == '-':\n",
    "            s = s[1:]\n",
    "        ismi = False\n",
    "        for i in range(len(s)):\n",
    "            if s[i] == 'e':\n",
    "                s1 = s[:i]\n",
    "                if i == len(s) - 1:\n",
    "                    return False\n",
    "                s2 = s[i+1:]\n",
    "                ismi = True\n",
    "                break\n",
    "        if ismi:\n",
    "            if s2[0] == '+' or s2[0] == '-':\n",
    "                s2 = s2[1:]\n",
    "            if isnoe(s1) and isnodot(s2):\n",
    "                return True\n",
    "        else:\n",
    "            return isnoe(s)\n",
    "                    \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            num = float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            key=float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        #print(s)\n",
    "        dot_seen = False\n",
    "        e_seen = False\n",
    "        num_seen = False\n",
    "        for i, a in enumerate(s):\n",
    "            if a.isdigit():\n",
    "                num_seen = True\n",
    "            elif a == \".\":\n",
    "                if e_seen or dot_seen:\n",
    "                    return False\n",
    "                dot_seen = True\n",
    "            elif a == \"e\":\n",
    "                if e_seen or not num_seen:\n",
    "                    return False\n",
    "                num_seen = False\n",
    "                e_seen = True\n",
    "            elif a in \"+-\":\n",
    "                if i > 0 and s[i - 1] != \"e\":\n",
    "                    return False\n",
    "            else:\n",
    "                return False\n",
    "        return num_seen\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            key = float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        \n",
    "        \n",
    "        \n",
    "        # public solution ... 44 ms ... 80 % ... 13.5 MB ... 7 %\n",
    "        #  time: O(n)\n",
    "        # space: O(1)\n",
    "        \n",
    "        s = s.strip()\n",
    "        dot_seen = e_seen = digit_seen = False\n",
    "        for i, ch in enumerate(s):\n",
    "            if ch in '+-':\n",
    "                if i > 0 and s[i-1] != 'e':   # 正负号的左侧邻居必须是 e\n",
    "                    return False\n",
    "            elif ch == '.':\n",
    "                if dot_seen or e_seen:        # 小数点不能出现 2 次。。。小数点不能出现在 e 后面\n",
    "                    return False\n",
    "                dot_seen = True\n",
    "            elif ch == 'e':\n",
    "                if e_seen or not digit_seen:  # e 不能出现 2 次。。。e 的前面必须存在 digit\n",
    "                    return False\n",
    "                e_seen = True\n",
    "                digit_seen = False            # 遇到 e 之后，把 digit_seen 重置为 False。。。确保 e 的后面必须同样存在 digit！\n",
    "            elif ch.isdigit():\n",
    "                digit_seen = True\n",
    "            else:\n",
    "                return False                  # 除了 +-.e 和 0 ~ 9，其他字符无效\n",
    "        return digit_seen\n",
    "        \n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        state = [\n",
    "            {},\n",
    "            {'blank': 1, 'sign': 2, 'digit': 3, 'dot': 4},\n",
    "            {'digit': 3, 'dot': 4},\n",
    "            {'digit': 3, 'dot': 5, 'e': 6, 'blank': 9},\n",
    "            {'digit': 5},\n",
    "            {'digit': 5, 'e': 6, 'blank': 9 },\n",
    "            {'sign': 7,'digit': 8},\n",
    "            {'digit': 8},\n",
    "            {'digit': 8, 'blank': 9},\n",
    "            {'blank': 9},\n",
    "        ]\n",
    "        cur = 1\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                c = 'digit'\n",
    "            elif c == ' ':\n",
    "                c = 'blank'\n",
    "            elif c == '.':\n",
    "                c = 'dot'\n",
    "            elif c in '+-':\n",
    "                c= 'sign'\n",
    "            if c not in state[cur]:\n",
    "                return False\n",
    "            cur = state[cur][c]\n",
    "        if cur not in [3, 5, 8, 9]:\n",
    "            return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        s=s.strip()\n",
    "        foundNum, foundNumAfter, foundDot, foundE=False, False, False, False\n",
    "        for i, c in enumerate(s):\n",
    "            if c.isdigit():\n",
    "                foundNum=True \n",
    "                foundNumAfter=True \n",
    "            elif c=='e':\n",
    "                if foundE or not foundNum:\n",
    "                    return False \n",
    "                foundE=True \n",
    "                foundNumAfter=False \n",
    "            elif c=='.':\n",
    "                if foundDot or foundE:\n",
    "                    return False\n",
    "                foundDot=True \n",
    "            elif c in '+-':\n",
    "                if i>0 and s[i-1]!='e':\n",
    "                    return False \n",
    "            else:\n",
    "                return False \n",
    "        return foundNum and foundNumAfter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        s=s.strip()\n",
    "        foundNum, foundNumAfter, foundDot, foundE=False, False, False, False\n",
    "        for i, c in enumerate(s):\n",
    "            if c.isdigit():\n",
    "                foundNum=True \n",
    "                foundNumAfter=True \n",
    "            elif c=='e':\n",
    "                if foundE or not foundNum:\n",
    "                    return False \n",
    "                foundE=True \n",
    "                foundNumAfter=False \n",
    "            elif c=='.':\n",
    "                if foundDot or foundE:\n",
    "                    return False\n",
    "                foundDot=True \n",
    "            elif c in '+-':\n",
    "                if i>0 and s[i-1]!='e':\n",
    "                    return False \n",
    "            else:\n",
    "                return False \n",
    "        return foundNum and foundNumAfter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from re import compile,match\n",
    "class Solution:\n",
    "\tdef isNumber(self,s):\n",
    "\t\tpattern=compile(r\"[+-]{0,1}(?:\\d*\\.\\d+|\\d+\\.\\d*|\\d+)\")\n",
    "\t\ts=s.strip()\n",
    "\t\ta,b,c=s.partition(\"e\")\n",
    "\t\t#print(f\"a:{a},b:{b},c:{c}\")\n",
    "\t\tif not b: #中间没有e的存在\n",
    "\t\t\ttry:\n",
    "\t\t\t\tif a==pattern.match(a).group():\n",
    "\t\t\t\t\treturn True\n",
    "\t\t\t\treturn False\n",
    "\t\t\texcept AttributeError:\n",
    "\t\t\t\treturn False\n",
    "\t\telse:\n",
    "\t\t\ttry:\n",
    "\t\t\t\tif a==pattern.match(a).group() and c==pattern.match(c).group() and \".\" not in c:\n",
    "\t\t\t\t\treturn True\n",
    "\t\t\t\treturn False\n",
    "\t\t\texcept AttributeError:\n",
    "\t\t\t\treturn False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import ast\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            r = s.strip()\n",
    "            index = -1\n",
    "            for c in range(len(r)):\n",
    "                if r[c] in ['-', '+']:\n",
    "                    continue\n",
    "                if r[c] != '0' or (c+1 < len(r) and (r[c+1] == '.' or r[c+1] == 'e')):\n",
    "                    index = c\n",
    "                    break\n",
    "            if index != -1:\n",
    "                r = r[index:]\n",
    "            print(r)\n",
    "            a = ast.literal_eval(r)\n",
    "            print(type(a))\n",
    "            if isinstance(a, str) or r == '...':\n",
    "                return False\n",
    "        except Exception as e:\n",
    "            print(e)\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        pattern = r'^\\s*[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?\\s*$'\n",
    "        return bool(re.match(pattern, s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            if \"inf\" in s or \"Inf\" in s:\n",
    "                raise ValueError\n",
    "            f = float(s)\n",
    "            return True\n",
    "        except ValueError:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        def isfloat(string):\n",
    "            if '.' not in string:\n",
    "                return False\n",
    "            if string[0] in ['+', '-']:\n",
    "                string = string[1:]\n",
    "                if len(string) == 0:\n",
    "                    return False\n",
    "            str_list = string.split('.')\n",
    "            n = len(str_list)\n",
    "            if n > 2:\n",
    "                return False\n",
    "            if n == 1:\n",
    "                string_all = str_list[0]\n",
    "                for num in string_all:\n",
    "                    if num < '0' or num > '9':\n",
    "                        return False\n",
    "            else:\n",
    "                if str_list[0] == str_list[1] == '':\n",
    "                    return False\n",
    "                if str_list[0] != '':\n",
    "                    for num in str_list[0]:\n",
    "                        if num < '0' or num > '9':\n",
    "                            return False\n",
    "                if str_list[1] != '':\n",
    "                    for num in str_list[1]:\n",
    "                        if num < '0' or num > '9':\n",
    "                            return False\n",
    "            return True\n",
    "        \n",
    "        def isInt(string):\n",
    "            if string[0] in ['+', '-']:\n",
    "                string = string[1:]\n",
    "                if len(string) == 0:\n",
    "                    return False\n",
    "            for num in string:\n",
    "                if num < '0' or num > '9':\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        if 'e' in s:\n",
    "            s = s.split('e')\n",
    "        else:\n",
    "            s = s.split('E')\n",
    "        if len(s) > 2:\n",
    "            return False\n",
    "        if len(s) == 1:\n",
    "            if not isfloat(s[0]) and not isInt(s[0]):\n",
    "                return False\n",
    "        else:\n",
    "            if s[0] == '' or s[1] == '':\n",
    "                return False\n",
    "            else:\n",
    "                if (not isfloat(s[0]) and not isInt(s[0])) or not isInt(s[1]):\n",
    "                    return False\n",
    "        \n",
    "        return True\n",
    "                \n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        def isfloat(string):\n",
    "            if '.' not in string:\n",
    "                return False\n",
    "            if string[0] in ['+', '-']:\n",
    "                string = string[1:]\n",
    "                if len(string) == 0:\n",
    "                    return False\n",
    "            str_list = string.split('.')\n",
    "            n = len(str_list)\n",
    "            if n > 2:\n",
    "                return False\n",
    "            if n == 1:\n",
    "                string_all = str_list[0]\n",
    "                for num in string_all:\n",
    "                    if num < '0' or num > '9':\n",
    "                        return False\n",
    "            else:\n",
    "                if str_list[0] == str_list[1] == '':\n",
    "                    return False\n",
    "                if str_list[0] != '':\n",
    "                    for num in str_list[0]:\n",
    "                        if num < '0' or num > '9':\n",
    "                            return False\n",
    "                if str_list[1] != '':\n",
    "                    for num in str_list[1]:\n",
    "                        if num < '0' or num > '9':\n",
    "                            return False\n",
    "            return True\n",
    "        \n",
    "        def isInt(string):\n",
    "            if string[0] in ['+', '-']:\n",
    "                string = string[1:]\n",
    "                if len(string) == 0:\n",
    "                    return False\n",
    "            for num in string:\n",
    "                if num < '0' or num > '9':\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        if 'e' in s:\n",
    "            s = s.split('e')\n",
    "        else:\n",
    "            s = s.split('E')\n",
    "        if len(s) > 2:\n",
    "            return False\n",
    "        if len(s) == 1:\n",
    "            if not isfloat(s[0]) and not isInt(s[0]):\n",
    "                return False\n",
    "        else:\n",
    "            if s[0] == '' or s[1] == '':\n",
    "                return False\n",
    "            else:\n",
    "                if (not isfloat(s[0]) and not isInt(s[0])) or not isInt(s[1]):\n",
    "                    return False\n",
    "        \n",
    "        return True\n",
    "                \n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch: str) -> Chartype:\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            typ = toChartype(ch)\n",
    "            if typ not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][typ]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            if s in ['inf', '-inf', '+inf', 'Infinity', '-Infinity', '+Infinity', 'nan']:\n",
    "                return False\n",
    "            float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        # 小数：'^[+-]?\\d+\\.$','^[+-]?\\d+\\.\\d+$','^[+-]?\\.\\d+$'\n",
    "        # 整数：'^[+-]?\\d+'\n",
    "        # 合并小数和一种整数：'^[+-]?\\d+\\.?'\n",
    "        # 合并剩余两种整数：'^[+-]?\\d*\\.\\d+\n",
    "        # 前部分：^[+-]?((\\d+\\.?)|(\\d*\\.\\d+))\n",
    "        # 后部分：([eE][+-]?\\d+)\n",
    "        # 有效数字：(小数|整数)([eE]整数)?  即  ^[+-]?((\\d+\\.?)|(\\d*\\.\\d+))([eE][+-]?\\d+)?$\n",
    "        p = '^[+-]?((\\d+\\.?)|(\\d*\\.\\d+))([eE][+-]?\\d+)?$'\n",
    "        res = re.match(p, s)\n",
    "        return res!=None\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        num_show = dot_show = e_show = False\n",
    "        for i,char in enumerate(s):\n",
    "            if char.isdigit():\n",
    "                num_show = True\n",
    "            elif char in ['-', '+']:\n",
    "                if i > 0 and s[i-1] != 'e' and s[i-1] != 'E':\n",
    "                    return False\n",
    "            elif char == '.':\n",
    "                if dot_show or e_show:\n",
    "                    return False\n",
    "                dot_show = True\n",
    "            elif char == 'e' or char == 'E':\n",
    "                if e_show or not num_show:\n",
    "                    return False\n",
    "                e_show = True\n",
    "                num_show = False\n",
    "            else:\n",
    "                return False\n",
    "        return num_show\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        num_show = dot_show = e_show = False\n",
    "        for i, char in enumerate(s):\n",
    "            if char.isdigit():\n",
    "                num_show = True\n",
    "            elif char in ['-', '+']:\n",
    "                if i > 0 and s[i-1] != 'e' and s[i-1] != 'E':\n",
    "                    return False\n",
    "            elif char == '.':\n",
    "                if dot_show or e_show:\n",
    "                    return False\n",
    "                dot_show = True\n",
    "            elif char == 'e' or char == 'E':\n",
    "                if e_show or not num_show:\n",
    "                    return False\n",
    "                e_show = True\n",
    "                num_show = False\n",
    "            else:\n",
    "                return False\n",
    "        return num_show\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
